package com.hwpt.chesedemo.presentation.viewmodel

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.hwpt.chesedemo.presentation.component.BtPreferences
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class BluetoothViewModel @Inject constructor(
    @ApplicationContext private val context: Context,
    private val btPreferences: BtPreferences
) : ViewModel() {

    private val _state = MutableStateFlow(MainState())
    val state: StateFlow<MainState> = _state

    private lateinit var bluetoothAdapter: BluetoothAdapter
    private lateinit var bleScanner: BluetoothLeScanner
    private var enableBluetoothLauncher: ActivityResultLauncher<Intent>? = null
    private var permissionLauncher: ActivityResultLauncher<Array<String>>? = null
    private val handler = Handler(Looper.getMainLooper())
    private val SCAN_PERIOD = 15000L

    // 标记是否已经请求过权限，避免重复请求
    private var hasRequestedInitialPermissions = false

    private val scanCallback = object : ScanCallback() {
        override fun onScanResult(callbackType: Int, result: ScanResult) {
            handleScanResult(result.device, result.rssi)
        }

        override fun onScanFailed(errorCode: Int) {
            _state.update { it.copy(errorMessage = "扫描失败: ${translateErrorCode(errorCode)}") }
        }
    }

    private val classicReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothDevice.ACTION_FOUND -> {
                    val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                    val rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE)
                    device?.let { handleScanResult(it, rssi.toInt()) }
                }
                BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                    Log.d(TAG, "经典蓝牙扫描完成")
                }
            }
        }
    }

    init {
        initBluetooth()
        loadSavedDevice()
        // 初始化时检查权限状态（但不立即请求）
        checkInitialState()
    }

    private fun initBluetooth() {
        val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager
        bluetoothManager?.let {
            bluetoothAdapter = it.adapter
            if (bluetoothAdapter != null) {
                _state.update {
                    it.copy(
                        isBluetoothAvailable = true,
                        bluetoothStatus = "蓝牙硬件可用"
                    )
                }
            } else {
                _state.update {
                    it.copy(
                        isBluetoothAvailable = false,
                        bluetoothStatus = "此设备不支持蓝牙",
                        errorMessage = "设备不支持蓝牙功能"
                    )
                }
            }
        } ?: run {
            _state.update {
                it.copy(
                    isBluetoothAvailable = false,
                    bluetoothStatus = "蓝牙服务不可用",
                    errorMessage = "无法获取蓝牙服务"
                )
            }
        }
    }

    private fun checkInitialState() {
        viewModelScope.launch {
            // 检查基本权限
            val basicPermissionsGranted = checkBasicPermissions()
            if (basicPermissionsGranted) {
                // 检查蓝牙状态
                checkBluetoothState()
            } else {
                _state.update {
                    it.copy(
                        permissionStatus = "需要蓝牙权限",
                        isScanButtonEnabled = false
                    )
                }
            }
        }
    }

    private fun checkBasicPermissions(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            return ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_CONNECT
            ) == PackageManager.PERMISSION_GRANTED
        }
        return true
    }

    // 新增方法：初始权限检查并请求
    fun requestInitialPermissionsIfNeeded() {
        if (hasRequestedInitialPermissions) return

        viewModelScope.launch {
            // 获取所需的所有权限
            val requiredPermissions = getRequiredPermissions()

            // 检查哪些权限未授予
            val missingPermissions = requiredPermissions.filter { permission ->
                ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
            }

            if (missingPermissions.isNotEmpty()) {
                // 有缺失权限，显示提示并请求
                _state.update {
                    it.copy(
                        permissionStatus = "需要 ${missingPermissions.size} 个权限",
                        errorMessage = "需要授予权限才能使用蓝牙功能",
                        isScanButtonEnabled = false
                    )
                }

                // 延迟一下，确保UI已更新状态
                Handler(Looper.getMainLooper()).postDelayed({
                    permissionLauncher?.launch(missingPermissions.toTypedArray())
                    hasRequestedInitialPermissions = true
                }, 500)
            } else {
                // 所有权限都已授予，检查蓝牙状态
                _state.update {
                    it.copy(
                        permissionStatus = "权限已就绪",
                        errorMessage = null
                    )
                }
                checkBluetoothState()
            }
        }
    }

    // 新增方法：获取所有需要的权限
    private fun getRequiredPermissions(): List<String> {
        val requiredPermissions = mutableListOf<String>()

        // Android 12+ 需要新权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            requiredPermissions.addAll(listOf(
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT
            ))
        }

        // Android 10+ 需要位置权限用于蓝牙扫描
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            requiredPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requiredPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION)
        }

        return requiredPermissions
    }

    // 切换是否显示未知设备
    fun toggleShowUnknownDevices() {
        _state.update { currentState ->
            currentState.copy(
                showUnknownDevices = !currentState.showUnknownDevices,
                devices = getFilteredDevices(currentState.devices, !currentState.showUnknownDevices)
            )
        }
    }

    // 获取过滤后的设备列表（根据 showUnknownDevices 状态）
    private fun getFilteredDevices(devices: List<DeviceItem>, showUnknownDevices: Boolean): List<DeviceItem> {
        return if (!showUnknownDevices) {
            devices.filter { device ->
                // 过滤掉名称为"未知设备"或空名的设备
                device.name != "未知设备" && device.name.isNotBlank()
            }
        } else {
            devices
        }
    }

    private fun loadSavedDevice() {
        viewModelScope.launch {
            _state.update {
                it.copy(
                    hasSavedDevice = btPreferences.hasSavedDevice(),
                    savedDeviceName = btPreferences.getSavedDeviceName() ?: "",
                    savedDeviceAddress = btPreferences.getSavedDeviceAddress() ?: ""
                )
            }
        }
    }

    fun setEnableBluetoothLauncher(launcher: ActivityResultLauncher<Intent>) {
        enableBluetoothLauncher = launcher
    }

    fun setPermissionLauncher(launcher: ActivityResultLauncher<Array<String>>) {
        permissionLauncher = launcher
    }

    fun onBluetoothEnabled(resultOk: Boolean) {
        if (resultOk) {
            _state.update {
                it.copy(
                    isBluetoothEnabled = true,
                    bluetoothStatus = "蓝牙已开启",
                    errorMessage = null
                )
            }
            checkLocationAndEnable()
        } else {
            _state.update {
                it.copy(
                    isBluetoothEnabled = false,
                    bluetoothStatus = "蓝牙未开启",
                    errorMessage = "需要开启蓝牙才能扫描设备",
                    isScanButtonEnabled = false
                )
            }
        }
    }

    fun onPermissionsResult(grantResults: IntArray) {
        val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED }
        if (allGranted) {
            _state.update {
                it.copy(
                    permissionStatus = "权限已授予",
                    errorMessage = null
                )
            }
            checkBluetoothState()
        } else {
            _state.update {
                it.copy(
                    permissionStatus = "权限被拒绝",
                    errorMessage = "需要授予蓝牙和位置权限",
                    isScanButtonEnabled = false
                )
            }
        }
    }

    fun checkBluetoothState() {
        try {
            val isEnabled = bluetoothAdapter.isEnabled
            _state.update {
                it.copy(
                    isBluetoothEnabled = isEnabled,
                    bluetoothStatus = if (isEnabled) "蓝牙已开启" else "蓝牙未开启"
                )
            }

            if (isEnabled) {
                checkLocationAndEnable()
            } else {
                _state.update { it.copy(isScanButtonEnabled = false) }
            }
        } catch (e: SecurityException) {
            Log.e(TAG, "检查蓝牙状态权限异常", e)
            _state.update {
                it.copy(
                    errorMessage = "缺少蓝牙权限",
                    isScanButtonEnabled = false
                )
            }
        }
    }

    // 修改 toggleScan 方法，调用统一的权限检查
    fun toggleScan() {
        if (_state.value.isScanning) {
            stopScan()
        } else {
            if (checkAllPermissionsAndBluetooth()) {
                startScan()
            }
        }
    }

    // 修改权限检查方法，使其更通用
    private fun checkAllPermissionsAndBluetooth(): Boolean {
        val requiredPermissions = getRequiredPermissions()
        val missingPermissions = requiredPermissions.filter { permission ->
            ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
        }

        return if (missingPermissions.isEmpty()) {
            // 所有权限都已授予，检查蓝牙状态
            try {
                if (bluetoothAdapter.isEnabled) {
                    true
                } else {
                    requestEnableBluetooth()
                    false
                }
            } catch (e: SecurityException) {
                _state.update {
                    it.copy(
                        errorMessage = "缺少蓝牙权限，无法检查状态",
                        isScanButtonEnabled = false
                    )
                }
                false
            }
        } else {
            // 请求缺失的权限
            _state.update {
                it.copy(
                    permissionStatus = "请求权限: ${missingPermissions.size}个",
                    errorMessage = "需要权限才能扫描设备"
                )
            }
            permissionLauncher?.launch(missingPermissions.toTypedArray())
            false
        }
    }

    fun connectSavedDevice(): BluetoothDevice? {
        val address = _state.value.savedDeviceAddress
        if (address.isBlank()) return null

        return try {
            bluetoothAdapter.getRemoteDevice(address)
        } catch (e: Exception) {
            null
        }
    }

    fun unbindDevice() {
        viewModelScope.launch {
            btPreferences.clearSavedDevice()
            _state.update {
                it.copy(
                    hasSavedDevice = false,
                    savedDeviceName = "",
                    savedDeviceAddress = ""
                )
            }
        }
    }

    fun registerReceiver(context: Context) {
        try {
            val filter = IntentFilter().apply {
                addAction(BluetoothDevice.ACTION_FOUND)
                addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
            }
            ContextCompat.registerReceiver(context, classicReceiver, filter, ContextCompat.RECEIVER_EXPORTED)
        } catch (e: Exception) {
            Log.e(TAG, "注册广播接收器失败", e)
        }
    }

    fun unregisterReceiver(context: Context) {
        try {
            context.unregisterReceiver(classicReceiver)
        } catch (e: Exception) {
            Log.e(TAG, "注销广播接收器失败", e)
        }
    }

    // 私有方法
    private fun checkLocationAndEnable() {
        // Android 12+ 不需要位置权限进行蓝牙扫描
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            enableScanFunctionality()
            return
        }

        // Android 10-11 需要位置权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val locationPermission = Manifest.permission.ACCESS_FINE_LOCATION
            if (ContextCompat.checkSelfPermission(context, locationPermission) != PackageManager.PERMISSION_GRANTED) {
                _state.update {
                    it.copy(
                        errorMessage = "需要位置权限才能扫描BLE设备",
                        isScanButtonEnabled = false
                    )
                }
                return
            }
        }

        // Android 6-9 需要位置服务开启
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
            val isLocationEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
                    || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

            if (!isLocationEnabled) {
                _state.update {
                    it.copy(
                        bluetoothStatus = "需要开启位置服务",
                        errorMessage = "请开启位置服务以扫描BLE设备"
                    )
                }
                return
            }
        }

        enableScanFunctionality()
    }

    private fun enableScanFunctionality() {
        try {
            bleScanner = bluetoothAdapter.bluetoothLeScanner
            _state.update {
                it.copy(
                    isScanButtonEnabled = true,
                    bluetoothStatus = "蓝牙已开启，可以扫描设备",
                    errorMessage = null,
                    permissionStatus = "就绪"
                )
            }
        } catch (e: Exception) {
            Log.e(TAG, "启用扫描功能失败", e)
            _state.update {
                it.copy(
                    errorMessage = "初始化扫描器失败: ${e.message}",
                    isScanButtonEnabled = false
                )
            }
        }
    }

    private fun requestEnableBluetooth() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT)
                    != PackageManager.PERMISSION_GRANTED) {
                    _state.update {
                        it.copy(
                            errorMessage = "需要蓝牙连接权限",
                            isScanButtonEnabled = false
                        )
                    }
                    return
                }
            }

            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            enableBluetoothLauncher?.launch(enableBtIntent)
        } catch (e: Exception) {
            Log.e(TAG, "请求启用蓝牙失败", e)
            _state.update {
                it.copy(
                    errorMessage = "无法请求启用蓝牙: ${e.message}",
                    isScanButtonEnabled = false
                )
            }
        }
    }

    private fun startScan() {
        _state.update {
            it.copy(
                isScanning = true,
                bluetoothStatus = "正在扫描蓝牙设备...",
                devices = emptyList(),
                errorMessage = null
            )
        }

        try {
            startClassicScan()
            startBleScan()

            handler.postDelayed({ stopScan() }, SCAN_PERIOD)
        } catch (e: Exception) {
            Log.e(TAG, "开始扫描失败", e)
            _state.update {
                it.copy(
                    isScanning = false,
                    errorMessage = "开始扫描失败: ${e.message}"
                )
            }
        }
    }

    private fun stopScan() {
        if (!_state.value.isScanning) return

        _state.update {
            it.copy(
                isScanning = false,
                bluetoothStatus = "扫描完成"
            )
        }

        try {
            if (bluetoothAdapter.isDiscovering) {
                bluetoothAdapter.cancelDiscovery()
            }
            bleScanner.stopScan(scanCallback)
        } catch (e: Exception) {
            Log.e(TAG, "停止扫描异常", e)
        }

        handler.removeCallbacksAndMessages(null)

        // 扫描完成后重新排序一次，确保最终结果有序
        viewModelScope.launch {
            val sortedDevices = _state.value.devices.sortedByDescending { it.rssi }
            // 应用过滤
            val filteredDevices = getFilteredDevices(sortedDevices, _state.value.showUnknownDevices)
            _state.update { it.copy(devices = filteredDevices) }
        }
    }

    private fun startClassicScan() {
        try {
            if (bluetoothAdapter.isDiscovering) {
                bluetoothAdapter.cancelDiscovery()
            }
            bluetoothAdapter.startDiscovery()
        } catch (e: SecurityException) {
            Log.e(TAG, "经典蓝牙扫描权限异常", e)
        } catch (e: Exception) {
            Log.e(TAG, "经典蓝牙扫描失败", e)
        }
    }

    private fun startBleScan() {
        try {
            if (bleScanner == null) {
                bleScanner = bluetoothAdapter.bluetoothLeScanner
            }

            val settings = ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .build()

            bleScanner.startScan(null, settings, scanCallback)
        } catch (e: SecurityException) {
            Log.e(TAG, "BLE扫描权限异常", e)
            _state.update {
                it.copy(
                    errorMessage = "缺少BLE扫描权限"
                )
            }
        } catch (e: Exception) {
            Log.e(TAG, "BLE扫描失败", e)
            _state.update {
                it.copy(
                    errorMessage = "BLE扫描失败: ${e.message}"
                )
            }
        }
    }

    private fun handleScanResult(device: BluetoothDevice, rssi: Int) {
        viewModelScope.launch {
            try {
                val deviceName = try {
                    device.name ?: "未知设备"
                } catch (e: SecurityException) {
                    "未知设备"
                }

                val deviceItem = DeviceItem(
                    device = device,
                    name = deviceName,
                    address = device.address,
                    type = when (device.type) {
                        BluetoothDevice.DEVICE_TYPE_CLASSIC -> "经典蓝牙"
                        BluetoothDevice.DEVICE_TYPE_LE -> "BLE"
                        BluetoothDevice.DEVICE_TYPE_DUAL -> "双模"
                        else -> "未知"
                    },
                    rssi = rssi
                )

                // 获取当前设备列表
                val currentDevices = _state.value.devices.toMutableList()
                val existingIndex = currentDevices.indexOfFirst { it.address == device.address }

                if (existingIndex >= 0) {
                    // 更新现有设备
                    currentDevices[existingIndex] = deviceItem
                } else {
                    // 添加新设备
                    currentDevices.add(deviceItem)
                }

                // 按信号强度排序：信号强的（RSSI值更大）排在前面
                val sortedDevices = currentDevices.sortedByDescending { it.rssi }

                // 应用过滤
                val filteredDevices = getFilteredDevices(sortedDevices, _state.value.showUnknownDevices)

                _state.update { it.copy(devices = filteredDevices) }
            } catch (e: Exception) {
                Log.e(TAG, "处理扫描结果失败", e)
            }
        }
    }

    private fun translateErrorCode(errorCode: Int): String {
        return when (errorCode) {
            ScanCallback.SCAN_FAILED_ALREADY_STARTED -> "扫描已在进行中"
            ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> "应用注册失败"
            ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED -> "不支持此功能"
            ScanCallback.SCAN_FAILED_INTERNAL_ERROR -> "内部错误"
            else -> "未知错误: $errorCode"
        }
    }

    override fun onCleared() {
        super.onCleared()
        stopScan()
    }

    companion object {
        private const val TAG = "BluetoothViewModel"
    }
}

// MainState 数据结构
data class MainState(
    val bluetoothStatus: String = "蓝牙状态：检测中...",
    val isScanning: Boolean = false,
    val devices: List<DeviceItem> = emptyList(),
    val hasSavedDevice: Boolean = false,
    val savedDeviceName: String = "",
    val savedDeviceAddress: String = "",
    val isScanButtonEnabled: Boolean = false,
    val errorMessage: String? = null,
    val permissionStatus: String = "检查权限...",
    val isBluetoothEnabled: Boolean = false,
    val isBluetoothAvailable: Boolean = true,
    val isInitialPermissionChecked: Boolean = false,
    val showUnknownDevices: Boolean = true // 新增：是否显示未知设备
)

data class DeviceItem(
    val device: BluetoothDevice,
    val name: String,
    val address: String,
    val type: String,
    val rssi: Int
)